package com.xiaomi.shoppinglist

import android.content.ContentProvider
import android.content.ContentValues
import android.content.UriMatcher
import android.database.Cursor
import android.database.MatrixCursor
import android.net.Uri
import android.util.Log

class ShoppingListProvider : ContentProvider() {
    private val TAG = "ShoppingListProvider"
    private val AUTHORITY = "com.xiaomi.shoppinglist.provider"
    private val BASE_URI = Uri.parse("content://$AUTHORITY")
    private val ITEMS = 1
    private val ITEM_ID = 2

    private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
        addURI(AUTHORITY, "items", ITEMS)
        addURI(AUTHORITY, "items/#", ITEM_ID)
    }

    override fun onCreate(): Boolean {
        Log.d(TAG, "onCreate called")
        // 初始化数据库
        context?.let { ShoppingListDatabase.init(it) }
        return true
    }

    override fun query(
        uri: Uri,
        projection: Array<String>?,
        selection: String?,
        selectionArgs: Array<String>?,
        sortOrder: String?
    ): Cursor? {
        Log.d(TAG, "query called with uri: $uri")
        val context = context ?: return null
        val db = ShoppingListDatabase.getInstance(context)

        return when (uriMatcher.match(uri)) {
            ITEMS -> {
                // 查询所有项
                val items = kotlinx.coroutines.runBlocking {
                    db.shoppingItemDao().getActiveOneTimeItems() +
                            db.shoppingItemDao().getActiveRepeatableItems()
                }
                createCursorFromItems(items)
            }
            ITEM_ID -> {
                // 查询单个项
                val id = uri.lastPathSegment?.toLong() ?: return null
                val item = kotlinx.coroutines.runBlocking {
                    db.shoppingItemDao().getItemById(id)
                }
                item?.let { createCursorFromItems(listOf(it)) }
            }
            else -> {
                throw IllegalArgumentException("Unknown URI: $uri")
            }
        }
    }

    private fun createCursorFromItems(items: List<ShoppingItem>): Cursor {
        val cursor = MatrixCursor(arrayOf("_id", "name", "is_completed", "is_repeatable"))

        for (item in items) {
            cursor.addRow(arrayOf(
                item.id,
                item.name,
                if (item.isCompleted) 1 else 0,
                if (item.isRepeatable) 1 else 0
            ))
        }

        return cursor
    }

    override fun getType(uri: Uri): String? {
        return when (uriMatcher.match(uri)) {
            ITEMS -> "vnd.android.cursor.dir/vnd.com.xiaomi.shoppinglist.item"
            ITEM_ID -> "vnd.android.cursor.item/vnd.com.xiaomi.shoppinglist.item"
            else -> null
        }
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        Log.d(TAG, "insert called with uri: $uri")
        val context = context ?: return null
        val db = ShoppingListDatabase.getInstance(context)

        if (uriMatcher.match(uri) != ITEMS) {
            throw IllegalArgumentException("Unknown URI: $uri")
        }

        val name = values?.getAsString("name") ?: return null
        val isRepeatable = values.getAsBoolean("is_repeatable") ?: false

        val item = ShoppingItem(
            name = name,
            isCompleted = false,
            isRepeatable = isRepeatable,
            createTime = System.currentTimeMillis()
        )

        val id = kotlinx.coroutines.runBlocking {
            db.shoppingItemDao().insert(item)
        }

        return Uri.withAppendedPath(BASE_URI, "items/$id")
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        Log.d(TAG, "delete called with uri: $uri")
        val context = context ?: return 0
        val db = ShoppingListDatabase.getInstance(context)

        return when (uriMatcher.match(uri)) {
            ITEM_ID -> {
                val id = uri.lastPathSegment?.toLong() ?: return 0
                val item = kotlinx.coroutines.runBlocking {
                    db.shoppingItemDao().getItemById(id)
                }
                item?.let {
                    kotlinx.coroutines.runBlocking {
                        db.shoppingItemDao().delete(it)
                    }
                    1
                } ?: 0
            }
            else -> {
                throw IllegalArgumentException("Unknown URI: $uri")
            }
        }
    }

    override fun update(
        uri: Uri,
        values: ContentValues?,
        selection: String?,
        selectionArgs: Array<String>?
    ): Int {
        Log.d(TAG, "update called with uri: $uri")
        val context = context ?: return 0
        val db = ShoppingListDatabase.getInstance(context)

        return when (uriMatcher.match(uri)) {
            ITEM_ID -> {
                val id = uri.lastPathSegment?.toLong() ?: return 0
                val item = kotlinx.coroutines.runBlocking {
                    db.shoppingItemDao().getItemById(id)
                }
                item?.let {
                    values?.getAsString("name")?.let { name -> item.name = name }
                    values?.getAsBoolean("is_completed")?.let { completed -> item.isCompleted = completed }
                    values?.getAsBoolean("is_repeatable")?.let { repeatable -> item.isRepeatable = repeatable }
                    if (item.isCompleted) {
                        item.completedTime = System.currentTimeMillis()
                    }

                    kotlinx.coroutines.runBlocking {
                        db.shoppingItemDao().update(item)
                    }
                    1
                } ?: 0
            }
            else -> {
                throw IllegalArgumentException("Unknown URI: $uri")
            }
        }
    }
}